home *** CD-ROM | disk | FTP | other *** search
/ SGI Hot Mix 17 / Hot Mix 17.iso / HM17_SGI / research / examples / object / set_view.pro < prev    next >
Text File  |  1997-07-08  |  6KB  |  149 lines

  1. ;+
  2. ; NAME:
  3. ;       SET_VIEW
  4. ;
  5. ; PURPOSE:
  6. ;       This procedure sets a default VIEWPLANE_RECT for a given
  7. ;       view and destination.
  8. ;
  9. ;       The viewplane rect is calculated to hold the models that
  10. ;       are currently contained within the view.
  11. ;
  12. ; CATEGORY:
  13. ;       Object graphics.
  14. ;
  15. ; CALLING SEQUENCE:
  16. ;       SET_VIEW, oView, oDest
  17. ;
  18. ; INPUTS:
  19. ;       oView: An instance of an IDLgrView.
  20. ;       oDest: An instance of an IDLgrWindow or IDLgrPrinter.
  21. ;
  22. ; KEYWORD PARAMETERS:
  23. ;       DO_ASPECT: Set this keyword to a nonzero value if you would
  24. ;                       like to maintain aspect ratio of the bounds
  25. ;                       of the models within the viewport.
  26. ;       ISOTROPIC: Set this keyword to a nonzero value if you would
  27. ;                       like the bounds of the models to be isotropic.
  28. ;       XRANGE: Set this keyword to a two-element vector [xmin,xmax]
  29. ;                       to use as the bounds of the models.
  30. ;       YRANGE: Set this keyword to a two-element vector [ymin,ymax]
  31. ;                       to use as the bounds of the models.
  32. ;       ZRANGE: Set this keyword to a two-element vector [zmin,zmax]
  33. ;                       to use as the bounds of the models.
  34. ; MODIFICATION HISTORY:
  35. ;       Written by:     DD, February 1997.
  36. ;-
  37. PRO set_view, oView, oDest, XRANGE=xrange, YRANGE=yrange, ZRANGE=zrange, $
  38.               ISOTROPIC=isotropic, DO_ASPECT=do_aspect
  39.  
  40.     IF (N_ELEMENTS(isotropic) EQ 0) THEN isotropic = 0
  41.     IF (N_ELEMENTS(do_aspect) EQ 0) THEN do_aspect = 1
  42.  
  43.     ; Get the models contained within the view.
  44.     oModelArr = oView->Get(/ALL, COUNT=nModels)
  45.  
  46.     ; Determine the overall bounding box for the models within the view.
  47.     FOR i=0,nModels-1 DO BEGIN
  48.         get_bounds, oModelArr[i], modelXrange, modelYrange, modelZrange
  49.         IF (i EQ 0) THEN BEGIN
  50.             fullXrange = modelXrange
  51.             fullYrange = modelYrange
  52.             fullZrange = modelZrange
  53.         ENDIF ELSE BEGIN
  54.             fullXrange[0] = fullXrange[0] < modelXrange[0]
  55.             fullXrange[1] = fullXrange[1] > modelXrange[1]
  56.             fullYrange[0] = fullYrange[0] < modelYrange[0]
  57.             fullYrange[1] = fullYrange[1] > modelYrange[1]
  58.             fullZrange[0] = fullZrange[0] < modelZrange[0]
  59.             fullZrange[1] = fullZrange[1] > modelZrange[1]
  60.         ENDELSE
  61.     ENDFOR
  62.  
  63.     ; If user does not provide XYZRange, use overall model range.
  64.     IF (N_ELEMENTS(xrange) EQ 0) THEN xrange = fullXrange
  65.     IF (N_ELEMENTS(yrange) EQ 0) THEN yrange = fullYrange
  66.     IF (N_ELEMENTS(zrange) EQ 0) THEN zrange = fullZrange
  67.  
  68.         
  69.     ; If isotropy is to be maintained, use largest of three dimensions.
  70.     IF (isotropic NE 0) THEN BEGIN
  71.         xlen = xrange[1] - xrange[0]
  72.         ylen = yrange[1] - yrange[0]
  73.         zlen = zrange[1] - zrange[0]
  74.         maxlen = xlen > ylen > zlen
  75.         xrange[0] = xrange[0] - ((maxlen - xlen) / 2.0)
  76.         xrange[1] = xrange[0] + maxlen
  77.         yrange[0] = yrange[0] - ((maxlen - ylen) / 2.0)
  78.         yrange[1] = yrange[0] + maxlen
  79.         zrange[0] = zrange[0] - ((maxlen - zlen) / 2.0)
  80.         zrange[1] = zrange[0] + maxlen
  81.     ENDIF
  82.  
  83.     ; Pad in X and Y.
  84.     xpad = (xrange[1] - xrange[0]) * 0.1
  85.     ypad = (yrange[1] - yrange[0]) * 0.1
  86.     xrange[0] = xrange[0] - xpad
  87.     xrange[1] = xrange[1] + xpad
  88.     yrange[0] = yrange[0] - ypad
  89.     yrange[1] = yrange[1] + ypad
  90.  
  91.     ; Set viewplane rect according to given XYRanges.
  92.     IF (do_aspect) THEN BEGIN
  93.         ; Determine the dimensions of the viewport in device units.
  94.         oDest->GetProperty, DIMENSIONS=destDims, RESOLUTION=resolution
  95.         oView->GetProperty, DIMENSIONS=viewDims, UNITS=vUnits
  96.         ; If the view size is unspecified, use the destination dimensions.
  97.         IF ((viewDims[0] EQ 0) OR (viewDims[1] EQ 0)) THEN BEGIN
  98.             viewDims = destDims
  99.         ENDIF ELSE BEGIN
  100.             ; Translate to device units.
  101.             CASE vUnits OF
  102.                 0: BEGIN ;Device
  103.                      ; Do nothing.
  104.                    END
  105.                 1: BEGIN ; Inches
  106.                        viewDims = viewDims * 2.54 / resolution
  107.                    END
  108.                 2: BEGIN ; Centimeters
  109.                        viewDims = viewDims / resolution
  110.                    END
  111.                 3: BEGIN ; Normalized
  112.                        viewDims = viewDims * destDims
  113.                    END
  114.             ENDCASE
  115.         ENDELSE
  116.  
  117.         ; Calculate aspect ratio of viewport.
  118.         aspect = viewDims[0] / viewDims[1]
  119.  
  120.         ; Add padding to view volume to handle aspect ratio.
  121.         xlen = xrange[1] - xrange[0] 
  122.         ylen = yrange[1] - yrange[0] 
  123.         IF (aspect > 1.) THEN  BEGIN
  124.             vrect = [xrange[0] - (((aspect - 1.) * xlen )/2.),      $
  125.                      yrange[0],                                     $
  126.                      aspect * xlen,                                 $
  127.                      ylen]
  128.         ENDIF ELSE BEGIN
  129.             vrect = [xrange[0],                                     $
  130.                      yrange[0] - ((((1./aspect) - 1.) * ylen)/2.),  $
  131.                      xlen,                                          $
  132.                      ylen/aspect]
  133.         ENDELSE
  134.     ENDIF ELSE BEGIN
  135.         vrect = [xrange[0],               $
  136.                  yrange[0],               $
  137.                  xrange[1] - xrange[0],   $
  138.                  yrange[1] - yrange[0]]
  139.     ENDELSE
  140.  
  141.     zclip = [zrange[1]+1,zrange[0]-1]
  142.  
  143.     ; Position the eye so that there is a 60 degree field of view.
  144.     ; Ensure the eye is positioned in front of the near clip plane.
  145.     eye = (((yrange[1]-yrange[0])/2.) / TAN(!DTOR*30.0)) > (zclip[0] + 1.0)
  146.  
  147.     oView->SetProperty, VIEWPLANE_RECT=vRect, ZCLIP=zclip, EYE=eye
  148. END
  149.